﻿using ViewMaker;
using System;
using System.Windows.Input;
using System.Collections.ObjectModel;
using ViewMaker.Core.Controls;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel;
using System.Collections.Generic;
using ViewMaker.Core.Utils;
using System.Windows.Controls;
using System.Collections;
using System.Diagnostics;

namespace ViewMaker.Core.Tests
{
    public class HelloWorld : ViewModelBase
    {
        public string Input { get; set; }
        public string Output
        {
            get { return output; }
            set { output = value; OnPropertyChanged("Output"); }
        }
        private string output;
        public ICommand ExecCommand { get { return CreateCommand(() => Output = "Hello " + Input); } }
    }

    //[ViewProperty(ViewControl.Properties.WindowState,"Maximized")]
    [ViewProperty(PanelViewControl.Properties.LoadCommand, "LoadCommand")]
    [ViewProperty(PanelViewControl.Properties.UnloadCommand, "UnloadCommand")]
    [ViewProperty(PanelViewControl.Properties.WindowClosingCommand, "ClosingCommand")]
    public class TestClass : ViewModelBase, IViewLayoutGeneratorProvider
    {
        [ViewProperty(TextBoxViewControl.Properties.HeaderHorizontalContentAlignment, LayoutHorizontalAlignment.Left)]
        public string Input { get; set; }

        public string Output
        {
            get { return _output; }
            set { _output = value; OnPropertyChanged("Output"); }
        }
        private string _output;

        public ICommand Exec { get { return CreateCommand(() => Output = Input); } }

        [Browsable(false)]
        public ICommand LoadCommand { get { return CreateCommand(() => this.ShowMessage("Loaded TestClass")); } }

        [Browsable(false)]
        public ICommand UnloadCommand { get { return CreateCommand(() => this.ShowMessage("Unloading TestClass")); } }

        [Browsable(false)]
        public ICommand ClosingCommand { get { return CreateCommand(Closing); } }

        public void Closing(object arg)
        {
            var cancelArgs = arg as CancelEventArgs;
            if (arg == null) return;
            cancelArgs.Cancel = !this.ShowOKCancel("閉じてよろしいですか");
        }

        #region IViewLayoutGeneratorProvider メンバー

        ViewLayoutItem IViewLayoutGeneratorProvider.Generate()
        {
            return ServiceLocator.GetService<IViewLayoutGenerator>().Generate(typeof(TestClass), LayoutGenerateFlag.All | LayoutGenerateFlag.WithoutName);

        }

        #endregion
    }

    #region TestViewModel

    [View(ViewControlType.StackPanel)]
    public class TestViewModel : ViewModelBase
    {
        [Browsable(true)]
        public IdData IdData { get; set; }

        [Required]
        [Display(Name = "名前")]
        [ViewProperty(TextBoxViewControl.Properties.LostFocusCommand, "GetNameCommand")]
        public string Name 
        {
            get { return _name; }
            set { this.ValidateProperty("Name", value); _name = value; }
        }
        private string _name;

        [Display(Name = "名前（確定）")]
        [ViewProperty(TextBoxViewControl.Properties.IsReadOnly, true)]
        public string Name2
        {
            get { return _name2; }
            set { _name2 = value; OnPropertyChanged("Name2"); }
        }
        private string _name2;

        [Display(Name = "日付")]
        [ViewProperty(ViewControl.Properties.Width, 100)]
        public DateTime? Date { get; set; }

        [Display(Name = "住所")]
        [View(ViewControlType.Canvas)]
        [ViewProperty(ViewControl.Properties.Height, 120)]
        public Address AddressX { get; set; }

        [Display(Name = "電話")]
        [View(ViewControlType.Literal)]
        [ViewProperty(LiteralViewControl.Properties.Literal, @"<TextBlock xmlns=""http://schemas.microsoft.com/winfx/2006/xaml/presentation"" >999-999-9999</TextBlock>")]
        public string Tel { get; set; }

        [Display(Name = "会員？")]
        public bool IsMember { get; set; }

        [Display(Name = "性別")]
        [View(ViewControlType.RadioButtonList)]
        [ViewProperty(RadioButtonListViewControl.Properties.ItemsSource, "GenderList")]
        [ViewProperty(RadioButtonListViewControl.Properties.Orientation, LayoutOrientation.Horizontal)]
        public Gender Gender
        {
            get { return _gender; }
            set { _gender = value; }
        }
        private Gender _gender;

        [Browsable(false)]
        public Gender[] GenderList { get { return _genderList; } }
        private Gender[] _genderList = new Gender[] { Gender.Male, Gender.Female };

        [Browsable(true)]
        [Display(Name = "アイテム一覧")]
        [ViewProperty(DataGridViewControl.Properties.Height, 100)]
        [ViewProperty(DataGridViewControl.Properties.DoubleClickCommand, "ShowSelected")]
        public ObservableCollection<TestItemViewModel> ListData { get; set; }

        [Browsable(false)]
        public ICommand ShowSelected { get { return CreateCommand((x)=>this.ShowMessage(x == null ? "null" : ((TestItemViewModel)x).Name )); } }

        [Display(Name = "住所")]
        [View(ViewControlType.TreeView)]
        [ViewProperty(TreeViewControl.Properties.ItemsSource, "Children")]
        [ViewProperty(TreeViewControl.Properties.DisplayMember, "Name")]
        [ViewProperty(TreeViewControl.Properties.Height, 100)]
        [ViewProperty(TreeViewControl.Properties.IsSelected, "IsSelected")]
        [ViewProperty(TreeViewControl.Properties.SelectedObject, "SelectedAddressNode")]
        public ObservableCollection<AddressNode> AddressNodeList { get; set; }

        [Browsable(false)]
        public AddressNode SelectedAddressNode { get; set; }

        public TestViewModel()
        {
            IdData = new IdData { Id = 1 };
            Name = "日本太郎";
            AddressX = new Address();

            AddressX.ViewCommandNotified += new EventHandler<ViewCommandEventArgs>(AddressViewCommandNotified);
            ListData = new ObservableCollection<TestItemViewModel>()
            {
                new  TestItemViewModel { Name="山田太郎", Enterdate=DateTime.Today, IsMember =true},
                new  TestItemViewModel { Name="鈴木花子", Enterdate=DateTime.Parse("2000/1/1"), IsMember =false}
            };
            Gender = Gender.Female;
            Tel = "999-9999-9999";
            AddressNodeList = new ObservableCollection<AddressNode>();
            var n1 = new AddressNode { Name = "日本" };
            AddressNodeList.Add(n1);
            n1.Children.Add(new AddressNode { Name = "大阪" });
            n1.Children.Add(new AddressNode { Name = "東京" });
        }

        void AddressViewCommandNotified(object sender, ViewCommandEventArgs e)
        {
            ExecuteViewCommand(e.Command, e.Parameter);
        }

        [Browsable(false)]
        public ICommand GetNameCommand { get { return CreateCommand(()=>this.Name2 = this.Name); } }
    }

    public enum Gender
    {
        Male,
        Female
    }

    [View(typeof(IdUserControl))]
    public class IdData
    {
        public int? Id
        {
            get { return _id; }
            set { _id = value; }
        }
        private int? _id;
    }

    
    public class TestItemViewModel
    {
        [Display(Name = "名前")]
        public string Name { get; set; }
        [Display(Name = "会員？")]
        public bool IsMember { get; set; }
        [Display(Name = "入力日")]
        public DateTime Enterdate { get; set; }

        [Display(Name = "都道府県")]
        [View(ViewControlType.DataGridComboBoxColumn)]
        [ViewProperty(DataGridComboBoxColumnViewElement.Properties.ItemsSource, "TodoufukenList")]
        public string Todoufuken
        {
            get { return _todoufuken; }
            set { _todoufuken = value; }
        }
        private string _todoufuken;

        [Browsable(false)]
        public List<string> TodoufukenList
        {
            get
            {
                if (_todoufukenList == null)
                {
                    this._todoufukenList = new List<string>();
                    _todoufukenList.Add("OSAKA");
                    _todoufukenList.Add("TOKYO");
                    _todoufukenList.Add("FUKUOKA");
                    _todoufukenList.Add("NAGOYA");
                }
                return _todoufukenList;
            }
        }
        private List<string> _todoufukenList;
    }

    public class Address : ViewModelBase
    {
        [Display(Name = "都道府県")]
        [View(ViewControlType.ComboBox)]
        [ViewProperty(ComboBoxViewControl.Properties.ItemsSource, "TodoufukenList")]
        [ViewProperty(ComboBoxViewControl.Properties.DisplayMemberPath, "Name")]
        [ViewProperty(ComboBoxViewControl.Properties.SelectedValuePath, "Code")]
        [ViewProperty(ComboBoxViewControl.Properties.SelectionChangedCommand, "TodoufukenSelectedCommand")]
        public string Todoufuken
        {
            get { return _todoufuken; }
            set 
            { 
                _todoufuken = value;
                OnPropertyChanged("Todoufuken");
                OnPropertyChanged("TodoufukenSymbol");
            }
        }
        private string _todoufuken;


        [Display(Name = "シンボル")]
        [View(ViewControlType.Hyperlink)]
        [ViewProperty(HyperlinkViewControl.Properties.Command, "ShowDetailCommand")]
        public string TodoufukenSymbol
        {
            get { return _todoufukenSymbol; }
            set { _todoufukenSymbol = value; OnPropertyChanged("TodoufukenSymbol"); }
        }
        public string _todoufukenSymbol;


        [Display(Name = "住所１")]
        [ViewProperty(TextBoxViewControl.Properties.EnterKeyCommand, "GetAddressCommand")]
        public string Address1
        {
            get { return _address1; }
            set { _address1 = value; }
        }
        private string _address1;

        [Display(Name = "住所２")]
        public string Address2
        {
            get { return _address2; }
            set { _address2 = value; OnPropertyChanged("Address2"); }
        }
        private string _address2;

 
        public Address()
        {
            this._todoufukenList = new List<TodoufukenItem>();
            _todoufukenList.Add(new TodoufukenItem { Code = "OSAKA", Name = "大阪" });
            _todoufukenList.Add(new TodoufukenItem { Code = "TOKYO", Name = "東京" });
            _todoufukenList.Add(new TodoufukenItem { Code = "FUKUOKA", Name = "福岡" });
            _todoufukenList.Add(new TodoufukenItem { Code = "NAGOYA", Name = "名古屋" });
        }

        private List<TodoufukenItem> _todoufukenList;

        [Browsable(false)]
        public List<TodoufukenItem> TodoufukenList
        {
            get { return _todoufukenList; }
            set { _todoufukenList = value; }
        }

        [Browsable(false)]
        public ICommand GetAddressCommand { get { return CreateCommand(() => Address2 = Address1); } }

        [Browsable(false)]
        public ICommand TodoufukenSelectedCommand
        {
            get
            {
                return this.CreateCommand((x) =>
                {
                    if (x == null) return;
                    foreach (TodoufukenItem item in (IList)x)
                    {
                        this.TodoufukenSymbol = item.Code;
                    }
                });
            }
        }

        [Browsable(false)]
        public ICommand ShowDetailCommand { get { return CreateCommand(ShowDetail); } }
        private void ShowDetail()
        {
            this.ShowMessage(this.Todoufuken + Environment.NewLine + this.Address1 + Environment.NewLine + this.Address2,"Detal");
        }

    }


    public class TodoufukenItem
    {
        public string Code { get; set; }
        public string Name { get; set; }
    }

    public class AddressNode
    {
        public string Name { get; set; }
        public bool IsSelected { get; set; }
        public ObservableCollection<AddressNode> Children { get; set; }

        public AddressNode()
        {
            Children = new ObservableCollection<AddressNode>();
        }

        public AddressNode GetSelectedNode()
        {
            if (IsSelected) return this;
            foreach (var child in Children)
            {
                var node = child.GetSelectedNode();
                if (node != null) return node;
            }
            return null;
        }
    }

    #endregion


}
